package com.qidian.blog.servlet;

import com.qidian.blog.factory.ServiceFactory;
import com.qidian.blog.pojo.BlogConfig;
import com.qidian.blog.service.BlogConfigService;
import com.qidian.blog.util.Const;
import com.qidian.blog.util.JSONTools;
import com.qidian.blog.util.pojo.QDResult;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Random;
import java.util.UUID;

/**
 * @Author 郭浩
 * @Date 2022/10/10 16:17
 */
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
    private BlogConfigService configService = ServiceFactory.getService(BlogConfigService.class);

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 读取项目的配置对象
        BlogConfig config = configService.query();

        // 创建一个工厂，用来做基本的配置
        DiskFileItemFactory factory = new DiskFileItemFactory();
        // 配置一个临时仓库(临时文件夹)  因为第三方组件将文件数据解析出来之后，需要放在一个临时文件夹中
        ServletContext servletContext = this.getServletConfig().getServletContext();
        String serverPath = servletContext.getRealPath("/");// 获取服务器上的程序根目录
        File repository = new File(serverPath,"temp");
        factory.setRepository(repository);
        // 创建文件上传的处理器
        ServletFileUpload upload = new ServletFileUpload(factory);
        // 解析请求（解析请求流中的数据）
        try {
            // FileItem表示表单域
            List<FileItem> items = upload.parseRequest(req);
            for (FileItem item : items){
                if(!item.isFormField()){// 普通的表单不做任何处理
                    // 文件域
                    //InputStream in = item.getInputStream();// 这个输入流就指向临时文件
                    // 我们可以使用文件拷贝的操作将临时文件的数据写入目标文件。
                    // FileItem提供了专门的文件拷贝的API，我们直接调用即可
                    // 准备一个目标文件夹，这个文件夹是从数据库读取的文件存储的磁盘的目录
                    File file = new File(config.getImagePath());
                    // 文件名
                    String fileName = item.getName();
                    // 一般的处理都是给磁盘上的文件生成一个物理名称， 然后文件的路径存储到数据库中
                    String ext = fileName.substring(fileName.lastIndexOf("."));
                    // 生成一个物理文件名
                    fileName = UUID.randomUUID().toString().replace("-","")+(new Random().nextInt(90) + 10) + ext;
                    file = new File(file,fileName);
                    // 使用FileItem的API拷贝文件
                    item.write(file);
                    // 删除临时文件
                    item.delete();
                    // 响应客户端  要响应文件的访问路径
                    String url = config.getImageServerUrl()+fileName;
                    QDResult result = QDResult.ok(url);
                    resp.setContentType(Const.RES_JSON);
                    resp.getWriter().write(JSONTools.object2json(result));
                    return;
                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        QDResult result = QDResult.fal("文件上传失败");
        resp.setContentType(Const.RES_JSON);
        resp.getWriter().write(JSONTools.object2json(result));
    }
}